<script setup lang="ts">
import { fetchRecordDetails, type LogDataRecord } from '@/api/admin/historyRecord'
import { useControlWebsocket, useDeviceWebsocket } from '@/hooks'
import { SESSION } from '@/utils/storage'

// ========================== 路由和查询参数 ==========================
const router = useRouter()
const route = useRoute()

const routeQuery = computed(() => ({
  medical_record_number: (route.query.medical_record_number as string) || '',
  created_date: (route.query.created_date as string) || '',
}))

// ========================== 播放控制相关 ==========================
const PLAYBACK_RATE_OPTIONS = [1, 2, 4, 8, 16] as const
const currentTimestamp = ref(0)
const currentPlaybackRate = ref<(typeof PLAYBACK_RATE_OPTIONS)[number]>(1)

/** 切换播放速率 */
const togglePlaybackRate = () => {
  const currentIndex = PLAYBACK_RATE_OPTIONS.indexOf(currentPlaybackRate.value)
  const nextIndex = (currentIndex + 1) % PLAYBACK_RATE_OPTIONS.length
  currentPlaybackRate.value = PLAYBACK_RATE_OPTIONS[nextIndex]
}

/** 帧控制 */
const navigateFrame = (direction: 'next' | 'prev') => {
  const step = parseFloat((currentPlaybackRate.value / 120).toFixed(2))
  const newTimestamp =
    direction === 'next' ? currentTimestamp.value + step : currentTimestamp.value - step

  const maxTimestamp = Number(
    gaitEventsList.value[gaitEventsList.value.length - 1]?.interval_end || 0,
  )

  if (newTimestamp < 0) {
    currentTimestamp.value = 0
  } else if (newTimestamp > maxTimestamp) {
    currentTimestamp.value = maxTimestamp
  } else {
    currentTimestamp.value = newTimestamp
  }

  // 检查缓存，使用currentTimestamp作为key
  const timestampKey = String(currentTimestamp.value)
  const cachedImage = imageCache.value.get(timestampKey)
  if (cachedImage) {
    currentDisplayImage.value = cachedImage
    return
  }

  // 请求新图像
  requestImageAnalysis(timestampKey)
}

// ========================== 图像处理相关 ==========================
const currentDisplayImage = ref('')
// imageCache: Map<timestamp, image>
// key为timestamp字符串，value为base64图片字符串
const imageCache = ref<Map<string, string>>(new Map())

interface GaitEventRow {
  step_id: number
  interval_end: string
  interval_start: number
  step_type: string
  end_frame?: number // 可选字段，用于帧控制
}

const selectGaitEventTime = (timestamp: string) => {
  currentTimestamp.value = Number(timestamp)

  // 检查缓存，使用timestamp作为key
  const timestampKey = String(timestamp)
  const cachedImage = imageCache.value.get(timestampKey)
  if (cachedImage) {
    currentDisplayImage.value = cachedImage
    return
  }

  // 请求新图像
  requestImageAnalysis(timestampKey)
}

const requestImageAnalysis = (timestamp: string) => {
  deviceWebsocketInstance?.send(
    JSON.stringify({
      command: 'dynamic_analysis',
      date: routeQuery.value.created_date.split('-').join(''),
      target_timestamp: timestamp,
      user_id: routeQuery.value.medical_record_number,
    }),
  )
}

const handleImageReceived = (imageData: string) => {
  const base64Image = `data:image/jpeg;base64,${imageData}`
  const timestampKey = String(currentTimestamp.value)

  // 将图片存储到缓存中
  imageCache.value.set(timestampKey, base64Image)
  currentDisplayImage.value = base64Image
}

// ========================== 统计数据 ==========================
const APPROACHING = ref<{ label: string; value: string }[]>([])

const LEAVING = ref<{ label: string; value: string }[]>([])

// ========================== Tab切换相关 ==========================
const TAB_INDICES = {
  STATISTICS: 0,
  CONTROL_PANEL: 1,
} as const

type TabIndex = (typeof TAB_INDICES)[keyof typeof TAB_INDICES]

const activeTabIndex = ref<TabIndex>(TAB_INDICES.STATISTICS)

const switchToTab = (tabIndex: TabIndex) => {
  activeTabIndex.value = tabIndex
}

// ========================== WebSocket管理 ==========================
let deviceWebsocketInstance: ReturnType<typeof useDeviceWebsocket>

const { send: sendControlCommand } = useControlWebsocket({
  onMessage: handleControlWebsocketMessage,
  onAlreadyConnected: () => {
    connectToDeviceWebsocket()
  },
})

function handleControlWebsocketMessage(response: any) {
  if (response?.status === 'success') {
    if (response.data?.device_name === 'gait_analysis' && response.data.ws_url) {
      SESSION.set('gait_analysis_ws_url', response.data.ws_url)
      connectToDeviceWebsocket()
    }
  }
}

const connectToDeviceWebsocket = () => {
  const websocketUrl = SESSION.get('gait_analysis_ws_url') || ''
  if (!websocketUrl) {
    ElMessage.error('未获取到步态分析设备 WebSocket 地址')
    return
  }

  deviceWebsocketInstance = useDeviceWebsocket(websocketUrl, {
    deviceName: 'gait_analysis',
    onMessage: handleDeviceWebsocketMessage,
  })

  deviceWebsocketInstance.open()
}

function handleDeviceWebsocketMessage(response: any) {
  if (response?.type === 'device_data' && response?.data?.type === 'mediapipe_image') {
    if (response.data.image) {
      handleImageReceived(response.data.image)
    }
  } else if (response?.type === 'device_data' && response?.data?.type === 'response') {
    const stage_analysis = response.data?.content?.stage_analysis
    if (stage_analysis) {
      Object.entries(stage_analysis.APPROACHING).forEach(([key, value]: [string, any]) => {
        if (key === '占比') {
          Object.entries(value).forEach(([subKey, subValue]) => {
            APPROACHING.value.push({ label: subKey, value: String(subValue) })
          })
        } else if (typeof value === 'object') {
          APPROACHING.value.push({ label: key, value: String(value.mean) })
        } else {
          APPROACHING.value.push({ label: key, value: String(value) })
        }
      })
      Object.entries(stage_analysis.LEAVING).forEach(([key, value]: [string, any]) => {
        if (key === '占比') {
          Object.entries(value).forEach(([subKey, subValue]) => {
            LEAVING.value.push({ label: subKey, value: String(subValue) })
          })
        } else if (typeof value === 'object') {
          LEAVING.value.push({ label: key, value: String(value.mean) })
        } else {
          LEAVING.value.push({ label: key, value: String(value) })
        }
      })
    }
  } else if (response.status === 'streaming_started') {
    deviceWebsocketInstance.send(
      JSON.stringify({
        command: 'analyse',
        date: routeQuery.value.created_date.split('-').join(''),
        user_id: routeQuery.value.medical_record_number,
      }),
    )
    // 初始化第一帧数据
    if (gaitEventsList.value.length > 0) {
      const firstEvent = gaitEventsList.value[0]
      currentTimestamp.value = Number(firstEvent.interval_start) || 0
      selectGaitEventTime(String(firstEvent.interval_start || 0)) // 默认显示开始时间的图片
    }
  }
}

// ========================== 数据获取相关 ==========================
const recordDetails = ref<LogDataRecord | null>(null)
const isLoading = ref(false)
const gaitEventsList = ref<GaitEventRow[]>([])

const fetchPatientRecordDetails = async () => {
  try {
    const response = await fetchRecordDetails(
      routeQuery.value.medical_record_number,
      routeQuery.value.created_date,
    )

    if (response) {
      recordDetails.value = response
      await fetchGaitEventsData()
    }
  } catch (error: any) {
    const errorMessage = error?.errorDetails?.description || error?.message || '未知错误'
    ElMessage.error(errorMessage)
  }
}

const fetchGaitEventsData = async () => {
  const gaitAnalysisFile = recordDetails.value?.gait_analysis?.['gait_events_analysis.json']
  if (!gaitAnalysisFile) {
    ElMessage.error('未获取到 gait_events_analysis.json 文件地址')
    return
  }

  const fileUrl = `http://localhost:8000/${gaitAnalysisFile}`.replace(/\\+/g, '/')
  isLoading.value = true

  try {
    const response = await fetch(fileUrl)
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`)
    }

    const data = await response.json()
    gaitEventsList.value = [...(data?.Stage_APPROACHING || []), ...(data?.Stage_LEAVING || [])]
  } catch (error: any) {
    ElMessage.error('获取步态分析数据失败')
    console.error('获取步态分析数据失败:', error)
  } finally {
    isLoading.value = false
  }
}

// ========================== 导航相关 ==========================
const navigateToFacialExpression = () => {
  router.push({
    path: '/facialExpression',
    query: {
      medical_record_number: routeQuery.value.medical_record_number,
      created_date: routeQuery.value.created_date,
    },
  })
}

const navigateBack = () => {
  router.push({
    path: '/singleRecord',
    query: {
      medical_record_number: routeQuery.value.medical_record_number,
    },
  })
}

// ========================== 生命周期管理 ==========================
const startGaitAnalysisDevice = () => {
  sendControlCommand(
    JSON.stringify({
      command: 'start_device',
      device_name: 'gait_analysis',
      token: SESSION.get('access_token') || '',
    }),
  )
}

const stopGaitAnalysisDevice = () => {
  sendControlCommand(
    JSON.stringify({
      command: 'stop_device',
      device_name: 'gait_analysis',
      token: SESSION.get('access_token') || '',
    }),
  )
}

const handlePageUnload = () => {
  deviceWebsocketInstance?.close()
  stopGaitAnalysisDevice()
}

onMounted(() => {
  startGaitAnalysisDevice()
  fetchPatientRecordDetails()

  window.addEventListener('beforeunload', handlePageUnload)
})

onBeforeUnmount(() => {
  handlePageUnload()
  window.removeEventListener('beforeunload', handlePageUnload)
})
</script>

<template>
  <el-row :gutter="16" class="h-full flex items-center">
    <!-- 图像显示区域 -->
    <el-col :span="10" class="h-full flex! items-center justify-center">
      <el-image :src="currentDisplayImage" fit="contain" class="w-full min-h-1/2" />
    </el-col>

    <!-- 步态事件列表 -->
    <el-col :span="8" class="h-full flex! flex-col">
      <div class="flex-1 min-h-0">
        <el-table
          v-loading="isLoading"
          :data="gaitEventsList"
          header-row-class-name="table-brand-header"
          height="100%"
          border
          stripe
        >
          <el-table-column type="index" label="序号" width="80" align="center" />
          <el-table-column prop="step_type" label="动作" align="center" show-overflow-tooltip />
          <el-table-column
            prop="interval_start"
            label="开始时间"
            align="center"
            show-overflow-tooltip
          >
            <template #default="{ row }">
              <div
                class="cursor-pointer text-blue-600 underline"
                @click="selectGaitEventTime(row.interval_start)"
              >
                {{ row.interval_start }}
              </div>
            </template>
          </el-table-column>
          <el-table-column
            prop="interval_end"
            label="结束时间"
            align="center"
            show-overflow-tooltip
          >
            <template #default="{ row }">
              <div
                class="cursor-pointer text-blue-600 underline"
                @click="selectGaitEventTime(row.interval_end)"
              >
                {{ row.interval_end }}
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <div class="flex items-center justify-evenly gap-4 text-xs mt-2">
        <div class="bg-#00BA3D text-white flex-1 py-2 rounded-lg text-center">已确认</div>
        <div class="bg-#05807B text-white flex-1 py-2 rounded-lg text-center">确认中</div>
        <div class="border border-#D1D1D1 flex-1 py-2 rounded-lg text-center">未确认</div>
      </div>
    </el-col>

    <!-- 右侧面板 -->
    <el-col :span="6" class="h-full">
      <!-- Tab切换器 -->
      <div class="indicator mb-4">
        <div
          v-for="(tabIndex, key) in TAB_INDICES"
          :key="key"
          class="dot"
          :class="{ active: activeTabIndex === tabIndex }"
          @click="switchToTab(tabIndex)"
        ></div>
      </div>

      <!-- Tab内容容器 -->
      <div class="tab-content-container">
        <!-- 统计 Tab -->
        <div class="tab-content" :class="{ active: activeTabIndex === TAB_INDICES.STATISTICS }">
          <el-descriptions
            title="步入统计"
            border
            :column="1"
            :style="{
              '--el-descriptions-item-bordered-label-background': '#fff',
            }"
          >
            <el-descriptions-item
              v-for="item in APPROACHING"
              :key="item.label"
              :label="item.label"
              label-width="50%"
              align="center"
            >
              {{ item.value }}
            </el-descriptions-item>
          </el-descriptions>

          <el-descriptions
            title="步出统计"
            border
            :column="1"
            :style="{
              '--el-descriptions-item-bordered-label-background': '#fff',
            }"
            class="mt-4"
          >
            <el-descriptions-item
              v-for="item in LEAVING"
              :key="item.label"
              :label="item.label"
              label-width="50%"
              align="center"
            >
              {{ item.value }}
            </el-descriptions-item>
          </el-descriptions>
        </div>

        <!-- 控制面板 Tab -->
        <div class="tab-content" :class="{ active: activeTabIndex === TAB_INDICES.CONTROL_PANEL }">
          <el-form :disabled="isLoading">
            <div class="flex justify-between items-center">
              <div>
                <div class="text-brand text-2xl">当前时间：</div>
                <div class="text-#00BA3D font-600 mt-4">
                  <span class="text-3xl">{{ currentTimestamp.toFixed(3) }}</span>
                </div>
              </div>
              <div class="text-brand font-500">
                <div class="text-lg">帧率倍数：</div>
                <el-button type="primary" class="mt-4" @click="togglePlaybackRate">
                  <span class="font-bold min-w-30">{{ `X ${currentPlaybackRate}` }}</span>
                </el-button>
              </div>
            </div>
            <el-button type="primary" class="w-full mt-4" @click="navigateFrame('next')">
              下一帧
            </el-button>
            <el-button class="brand-dark-button w-full mt-2" @click="navigateFrame('prev')">
              上一帧
            </el-button>
            <el-button type="primary" class="mt-8 w-full">设置当前帧为开始时间</el-button>
            <el-button type="primary" class="mt-2 w-full" @click="navigateToFacialExpression">
              下一步
            </el-button>
            <div class="flex mt-2 gap-2">
              <el-button type="danger" class="flex-1">删除当前</el-button>
              <el-button class="brand-dark-button flex-1" @click="navigateBack">
                返回上一页
              </el-button>
            </div>
          </el-form>
        </div>
      </div>
    </el-col>
  </el-row>
</template>

<style lang="css" scoped>
/* ========================== Element Plus 组件样式重写 ========================== */
:deep(.el-descriptions__header) {
  --el-text-color-primary: #fff;
  margin-bottom: 0 !important;
  height: 40px !important;
  background-color: var(--el-color-primary) !important;
  justify-content: center;
  font-size: 14px !important;
}

:deep(.el-button) {
  padding: 18px 15px;
}

:deep(.el-image__error) {
  height: 30vh;
}

/* ========================== 状态指示器样式 ========================== */
.confirm {
  background-color: #00ba3d;
  color: #fff;
}

.confirming {
  background-color: #05807b;
  color: #fff;
}

/* ========================== Tab切换器样式 ========================== */
.indicator {
  position: relative;
  display: flex;
  justify-content: center;
  gap: 16px;
  padding: 8px 0;
  background-color: #f5f5f5;
  border-radius: 8px;
}

.dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: #d1d1d1;
  cursor: pointer;
  transition: all 0.3s ease;
  position: relative;
  z-index: 2;
}

.dot:hover {
  background-color: #a0a0a0;
  transform: scale(1.1);
}

.dot.active {
  background-color: var(--el-color-primary);
  box-shadow: 0 0 8px rgba(80, 139, 204, 0.4);
}

/* ========================== Tab内容样式 ========================== */
.tab-content-container {
  position: relative;
  overflow: hidden;
  min-height: 400px;
}

.tab-content {
  opacity: 0;
  transform: translateY(20px);
  transition: all 0.3s ease;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
  pointer-events: none;
  overflow: auto;
}

.tab-content.active {
  opacity: 1;
  transform: translateY(0);
  position: relative;
  pointer-events: auto;
}

.control-panel-header {
  border-bottom: 2px solid var(--el-color-primary);
  margin-bottom: 16px;
}
</style>
